<?php

	class CoreDevRPCStatus extends CoreRPCStatus
	{
		protected $_version = "1.0.0";

		/**
		 *  Encapsulate a value in a CDATA string
		 *  @name    _cdata
		 *  @type    method
		 *  @access  protected
		 *  @param   string value
		 *  @returns string
		 *  @syntax  Object->_cdata( string value );
		 */
		protected function _cdata( $sValue )
		{
			if ( !empty( $sValue ) || ($sValue === "0" ) )
				return "<![CDATA[{$sValue}]]>";
			return "";
		}


		/**
		 *  fetch the status reply XML
		 *  @name    fetch
		 *  @type    method
		 *  @access  public
		 *  @param   bool   error (true if reply should indicate an error)
		 *  @param   string message [optional]
		 *  @param   mixed  content (string or array containing additional info to send) [optional]
		 *  @returns string
		 *  @syntax  Object->fetch( bool error [, string message [, mixed content ] ] );
		 */
		public function fetch( $bError, $sMessage="", $mContent="" )
		{
			if ( !headers_sent() )
				header( "X-Status: " . get_class( $this ) . "/{$this->_version}" );

			if ( is_array( $mContent ) )
				$sContent = $this->_flattenArray( $mContent );
			else if ( is_object ( $mContent ) )
				$sContent =$this->_flattenObject( $mContent );
			else
				$sContent = $this->_cdata( $mContent );

			return "<reply status=\"" . ( $bError ? 'ERROR' : 'OK' ) . "\">\n" .
				   ( !empty( $sMessage ) ? "\t<message>" . $this->_cdata( $sMessage ) . "</message>\n" : "" ) .
				   ( !empty( $sContent ) ? "\t<content>{$sContent}</content>\n" : "" ) .
				   "</reply>";
		}


		/**
		 *  Write out an array into a multi-node XML string
		 *  @name    _flattenArray
		 *  @type    method
		 *  @access  protected
		 *  @param   array source
		 *  @returns string
		 *  @syntax  Object->_flattenArray( array source );
		 */
		protected function _flattenArray( $aSource, $sNumericKey="item" )
		{
			$sReturn = "";
			foreach( $aSource as $sKey=>$mValue )
			{
				if ( is_numeric( $sKey ) )
					$sKey = $sNumericKey;

				if ( is_array( $mValue ) )
					$sReturn .= "<{$sKey}>" . $this->_flattenArray( $mValue, $sKey ) . "</{$sKey}>";
				else if ( is_object ( $mValue ) )
				{
					$oK = $this->instance( "/" );
					$sKey = get_class( $mValue ) ? strtolower( str_ireplace( array_keys( $oK->_path ), "", get_class( $mValue ) ) ) : $sKey;
					$sReturn .= "<{$sKey}>" . $this->_flattenObject( $mValue, $sKey ) . "</{$sKey}>";
				}
				else
					$sReturn .= "<{$sKey}>" . $this->_cdata( $mValue ) . "</{$sKey}>";

			}
			return "{$sReturn}";
		}


		/**
		 *  Write out an object into a multi-node XML string
		 *  @name    _flattenObject
		 *  @type    method
		 *  @access  protected
		 *  @param   object source
		 *  @returns string
		 *  @syntax  Object->_flattenObject( array source );
		 */
		protected function _flattenObject( $oSource, $sNumericKey="item" )
		{
			$sReturn = "";
			foreach( $oSource as $sKey=>$mValue )
			{
				if ( is_numeric( $sKey ) )
					$sKey = $sNumericKey;

				if ( is_array( $mValue ) )
					$mValue = $this->_flattenArray( $mValue, $sKey );
				else if ( is_object ( $mValue ) )
				{
					$oK = $this->instance( "/" );
					$sKey = get_class( $oSource ) ? strtolower( str_ireplace( array_keys( $oK->_path ), "", get_class( $oSource ) ) ) : $sKey;
					$mValue = $this->_flattenObject( $mValue );
					$sReturn .= "<{$sKey}>{$mValue}</{$sKey}>";
				}
				else
					$mValue = $this->_cdata( $mValue );

				$sReturn .= "<{$sKey}>{$mValue}</{$sKey}>";
			}

			return "{$sReturn}";
		}
	}

?>